package bootstrap

import (
	"flag"
	"github.com/gogf/gf/g/os/glog"
	"github.com/spf13/viper"
	"reflect"
	"usertodo/pkg/config"
)

// BootApplication: 应用程序结构体
type BootApplication struct {
	IsTest     bool
	conf       *viper.Viper
	starterCtx StarterContext
}

// init: 程序初始化
func (b *BootApplication) init() {
	glog.Info("配置初始化中...")
	for _, v := range GetStarters() {
		typ := reflect.TypeOf(v)
		glog.Debugf("初始化: PriorityGroup=%d,Priority=%d,type=%s", v.PriorityGroup(), v.Priority(), typ.String())
		v.Init(b.starterCtx)
	}
}

// setup: 程序安装
func (b *BootApplication) setup() {
	glog.Debugf("程序安装...")
	for _, v := range GetStarters() {
		typ := reflect.TypeOf(v)
		glog.Debugf("初始化: PriorityGroup=%d,Priority=%d,type=%s", v.PriorityGroup(), v.Priority(), typ.String())
		v.Init(b.starterCtx)
	}
}

// start: 程序开始运行，开始接受调用
func (e *BootApplication) start() {
	glog.Info("Starting starters...")
	for i, v := range GetStarters() {
		typ := reflect.TypeOf(v)
		glog.Debug("Starting: ", typ.String())
		if v.StartBlocking() {
			// 如果是最后一个可阻塞的，直接启动并阻塞
			if i+1 == len(GetStarters()) {
				v.Start(e.starterCtx)
			} else {
				// 如果不是，使用goroutine来异步启动，
				// 防止阻塞后面starter
				go v.Start(e.starterCtx)
			}
		} else {
			v.Start(e.starterCtx)
		}
	}
}

// Stop: 程序停止运行，停止接收请求,释放资源
func (e *BootApplication) Stop() {
	glog.Info("Stoping starters...")
	for _, v := range GetStarters() {
		typ := reflect.TypeOf(v)
		glog.Debug("Stoping: ", typ.String())
		v.Stop(e.starterCtx)
	}
}

/****************************************
/ 程序启动入口
/***************************************/
func Start() {
	// 0. 读取配置文件
	cfgPath := new(string)
	flag.StringVar(cfgPath, "c", "conf.yaml", "指定配置文件")
	flag.Parse()
	conf := config.NewConfig(*cfgPath)
	b := &BootApplication{conf: conf, starterCtx: StarterContext{}}

	// 1. 初始化starter
	b.init()
	// 2. 安装starter
	b.setup()
	// 3. 启动starter
	b.start()
}
